package com.zeedev.flyingsaucer.data;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv.Beers;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv.Members;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv.Members.MemberBeer;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv.Stores;
import mobi.zeedev.flyingsaucer.common.DataModule.FlyingSaucerConv.Stores.StoreBeer;
import mobi.zeedev.flyingsaucer.common.DataModule.Util;

import java.util.*;

public class FlyingSaucerProvider extends ContentProvider {

    private static final UriMatcher sUriMatcher;

    private BeerDataHelper2 mOpenHelper;

    private SQLiteDatabase transactionDb = null;


    private static Map<String, String> sMemberMap;

    private static HashMap<String, String> sStoresMap;

    private static HashMap<String, String> sBeersMap;

//	private static HashMap<String, String> sBeersProjectionMap;

    private static HashMap<String, String> sStoresBeersMap;

//	private static HashMap<String, String> sBeersProjectionMapOverLay;

    private static HashMap<String, String> sMemberBeerMap;


//	public static final String BEERS_TABLE_NAME = "BEERS";
//	public static final String STORES_TABLE_NAME = "STORES";
//	public static final String STORES_BEERS_TABLE_NAME = "STORES_BEERS";

    public static final int VERSION = 14;

    public static final String TAG = "FlyingSaucerProvider";


    //URIS

    //Beers
    private static final int BEERS_BASE = 200;
    private static final int BEERS = BEERS_BASE + 1;
    private static final int BEER_DB_ID = BEERS_BASE + 2;
    private static final int BEERS_FILTER = BEERS_BASE + 7;

    //StoresPreferencesModel

    private static final int STORES_BASE = 300;
    private static final int STORES = STORES_BASE + 3;
    private static final int STORES_DB_ID = STORES_BASE + 4;

    private static final int STORES_BEERS = STORES_BASE + 10;

    private static final int STORES_BEERS_DB_ID = STORES_BASE + 11;

    private static final int STORES_BEERS_FILTER = STORES_BASE + 12;


    private static final int MEMBERS_BASE = 100;

    private static final int MEMBERS = MEMBERS_BASE + 1;

    private static final int MEMBERS_ID = MEMBERS_BASE + 2;

    private static final int MEMBERS_ID_BEERS = MEMBERS_BASE + 3;

    private static final int MEMBERS_ID_BEERS_ID = MEMBERS_BASE + 4;

    private static final int MEMBERS_BEERS = MEMBERS_BASE + 5;

//	private static final int MEMBERS_BEERS_TASTED_DATES_ID = MEMBERS_BASE + 13;

    private static final int MEMBERS_BEERS_ID = MEMBERS_BASE + 14;

    private static final int MEMBERS_BEERS_FILTER = MEMBERS_BASE + 15;

    private static final int STORES_BEERS_ID = MEMBERS_BASE + 16;


    @Override
    public boolean onCreate() {
        //public BeerDataHelper(Context context, String dbNameIn, String tableNameIn, int versionIn) {
        // FIX THIS
        //public BeerDataHelper(Context context, String dbNameIn, String tableNameIn, int versionIn) {
        mOpenHelper = new BeerDataHelper2(this.getContext(), "FlyingSaucer.sql.db", VERSION);
        return true;
    }

    public SQLiteDatabase getInternalWritableDatabase() {
        if (this.transactionDb == null) {
            this.transactionDb = mOpenHelper.getWritableDatabase();
        }
        return this.transactionDb;
    }

    public void setNullInternalWritableDatabase() {
        this.transactionDb = null;
    }


/*    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {

        Date now = Calendar.getInstance().getTime();
        SQLiteDatabase db = getInternalWritableDatabase();
        db.beginTransaction();

        for (ContentProviderOperation op : operations) {
            int matchedUri = sUriMatcher.match(op.getUri());
            switch (matchedUri) {
                case STORES:

                    ContentProviderResult cpr = op.apply(this, null, 0);
                    if (cpr.count < 1) {
                        ContentProviderOperation.newInsert(cpr.uri).
                    }



                    break;
                default:
//                    throw new IllegalArgumentException("Unknown URI " + op.getUri());
                    super.applyBatch(operations);

            }


        }


//        return super.applyBatch(operations);
    }*/

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
            case BEERS:
                count = db.delete(Beers.TABLE, where, whereArgs);
                break;

            case BEER_DB_ID:
                String beerDbId = uri.getPathSegments().get(1);
                count = db.delete(Beers.TABLE, Beers.BEERS_KEY + "=" + beerDbId
                        + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                break;

            case STORES:
                count = db.delete(Stores.TABLE, where, whereArgs);
                break;

            case STORES_DB_ID:
                String storeDbId = uri.getPathSegments().get(1);
                count = db.delete(Stores.TABLE, Stores.STORES_KEY + "=" + storeDbId
                        + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                break;

            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public String getType(Uri uri) {
        switch (sUriMatcher.match(uri)) {

            case BEERS:
                return Beers.CONTENT_TYPE;

            case BEER_DB_ID:
                return Beers.CONTENT_ITEM_TYPE;

            case STORES:
                return Stores.CONTENT_TYPE;

            case STORES_DB_ID:
                return Stores.CONTENT_ITEM_TYPE;


            case BEERS_FILTER:
                return Beers.CONTENT_TYPE;


            case STORES_BEERS:
                return Stores.StoreBeer.CONTENT_TYPE;

            case STORES_BEERS_DB_ID:
                return Stores.StoreBeer.CONTENT_ITEM_TYPE;

            case STORES_BEERS_FILTER:
                return Stores.StoreBeer.CONTENT_TYPE;

            case STORES_BEERS_ID:
                return MemberBeer.CONTENT_TYPE;


            case MEMBERS:
                return Members.CONTENT_TYPE;
            case MEMBERS_ID:
                return Members.CONTENT_ITEM_TYPE;
            case MEMBERS_ID_BEERS:
                return MemberBeer.CONTENT_TYPE;
            case MEMBERS_ID_BEERS_ID:
                return MemberBeer.CONTENT_ITEM_TYPE;
            case MEMBERS_BEERS:
                return MemberBeer.CONTENT_TYPE;

//        case MEMBERS_BEERS_TASTED_DATES_ID:
//        	return MemberBeer.CONTENT_TYPE;
            case MEMBERS_BEERS_ID:
                return MemberBeer.CONTENT_ITEM_TYPE;
            case MEMBERS_BEERS_FILTER:
                return MemberBeer.CONTENT_TYPE;


            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
        int matchedUri = sUriMatcher.match(uri);

//		if ( 
//				matchedUri != BEERS		|| 
//				matchedUri != STORES	||
//				matchedUri !=  STORES_BEERS_DB_ID    		
//        ) {
//            throw new IllegalArgumentException("Unknown URI " + uri);
//        }

        ContentValues values;
        if (initialValues != null) {
            values = new ContentValues(initialValues);
        } else {
            values = new ContentValues();
        }


//        Long now = Long.valueOf(System.currentTimeMillis());

        if (matchedUri == MEMBERS) {
            SQLiteDatabase db = getInternalWritableDatabase();
            long rowId = db.insert(Members.TABLE, Members.UFO_MEMBER_ID, values);
            if (rowId > 0) {
                Uri noteUri = ContentUris.withAppendedId(Members.CONTENT_URI, rowId);
                getContext().getContentResolver().notifyChange(noteUri, null);
                return noteUri;
            }


        } else if (matchedUri == STORES) {
            SQLiteDatabase db = getInternalWritableDatabase();
            long rowId = db.insert(Stores.TABLE, Stores.NAME, values);
            if (rowId > 0) {
                Uri noteUri = ContentUris.withAppendedId(Stores.CONTENT_URI, rowId);
                getContext().getContentResolver().notifyChange(noteUri, null);
                return noteUri;
            }


        }
//        else if (matchedUri == STORES){
//
//	        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
//	        long rowId = db.insert(BEERS_TABLE_NAME, Beers.NAME, values);
//	        if (rowId > 0) {
//	            Uri noteUri = ContentUris.withAppendedId(FlyingSaucer.Beers.CONTENT_URI, rowId);
//	            getContext().getContentResolver().notifyChange(noteUri, null);
//	            return noteUri;
//	        }
//	
//	        
//        }     
        else if (matchedUri == STORES_BEERS) {
            SQLiteDatabase db = getInternalWritableDatabase();

//	        long beerRowId = db.insert(BEERS_TABLE_NAME, Beers.NAME, values);


//	        ContentValues cvStoresBeers = new ContentValues();
//	        cvStoresBeers.put(StoresPreferencesModel.Beers.STORE_DB_ID, uri.getPathSegments().get(1) );
//	        cvStoresBeers.put(StoresPreferencesModel.Beers.BEER_DB_ID, beerRowId );

            //row id of the stores-beer table
            long rowId = db.insert(Stores.StoreBeer.TABLE, Stores.StoreBeer.STORE_DB_ID, values);


            if (rowId > 0) {
                Uri storesBeerUri = ContentUris.withAppendedId(Stores.StoreBeer.CONTENT_URI, rowId);
//	            Uri beersUri = ContentUris.withAppendedId(Beers.CONTENT_URI, beerRowId);
                getContext().getContentResolver().notifyChange(storesBeerUri, null);
//	            getContext().getContentResolver().notifyChange(beersUri, null); 

                return storesBeerUri;
            }

        } else if (matchedUri == BEERS) {
            SQLiteDatabase db = getInternalWritableDatabase();
            long rowId = db.insert(Beers.TABLE, Beers.BEER_ID, values);
            if (rowId > 0) {
                Uri noteUri = ContentUris.withAppendedId(Beers.CONTENT_URI, rowId);
                getContext().getContentResolver().notifyChange(noteUri, null);
                return noteUri;
            }
        } else {
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        throw new SQLException("Failed to insert row into " + uri);

    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        Date now = Calendar.getInstance().getTime();
        int matchedUri = sUriMatcher.match(uri);
        int count = 0;

        if (matchedUri == STORES_BEERS) {
//        	Cursor t = query(Beers.CONTENT_URI, Util.asAr(Beers.BEER_ID, Beers.BEERS_KEY), null, null, null);
//        	ContentQueryMap ccc = new ContentQueryMap(t, Beers.BEER_ID, false, null);
            SQLiteDatabase db = getInternalWritableDatabase();
            db.beginTransaction();
            try {
                /*	Map<Integer, ContentValues> lookupMap = BeerDB.generateKeyMap(Arrays.asList(values));

                    Map<String, ContentValues> map = ccc.getRows();
    //	        	for (Entry<String, ContentValues> curEntry : map.entrySet()) {
                    for(ContentValues cv : values) {
                        Integer curBeerId = cv.getAsInteger(Beers.BEER_ID);

    //	        		int i = values.indexOf(beerId);
                        //find in content values
    //	        		int search = -1;
    //	        		for (int i = 0; i < values.length; i++) {
    //	        			if (values[i].getAsInteger(Beers.BEER_ID) == curBeerId )  {
    //	        				search = i;
    //	        				break;
    //	        			}
    //	        		}
    //	        		int i = 0;
    //	        		if (search != -1) {
    //	        			i = search;
    //	        		} else {
    //	        			//
    //	        			Log.d(TAG, "Error occured with this search");
    //	        		}

    //					if ( lookupMap.containsKey(  curBeerId ) ) {
    //						values[i].put(StoresPreferencesModel.Beers.ACTIVE, true);
    //						lookupMap.remove(curBeerId);
    //					}
    //					else {
    //						values[i].put(StoresPreferencesModel.Beers.ACTIVE, false);
    //					}
                        //TODO
                        //remove all those now not in the list... from the relationships table


                        ContentValues crCur = map.get(curBeerId.toString());
                        Long rowId = crCur.getAsLong(BaseColumns._ID);
                        cv.put(StoresPreferencesModel.StoreBeer.BEER_DB_ID, rowId);
                        cv.remove(Beers.BEER_ID);
                        String storeDbId = cv.getAsString(StoresPreferencesModel.StoreBeer.STORE_DB_ID);
    //					values[i].put(StoresPreferencesModel.Beers.ACTIVE, true);

                        int updateResult = db.update(StoresPreferencesModel.StoreBeer.TABLE, cv, StoresPreferencesModel.StoreBeer.BEER_DB_ID + "=? and " + StoresPreferencesModel.StoreBeer.STORE_DB_ID + "=?", Util.asAr(rowId, storeDbId ));

                        if (updateResult > 0) {
                            count = count + updateResult;
                            getContext().getContentResolver().notifyChange(uri, null);

                        } else {

                            //TODO ??? FIX THIS
                            if (cv.getAsLong(StoresPreferencesModel.StoreBeer.UPDATED_DATE) != null) {
                                cv.put(StoresPreferencesModel.StoreBeer.UPDATED_DATE, now.getTime());
                            }

                            long rowId1 = db.insert(StoresPreferencesModel.StoreBeer.TABLE, StoresPreferencesModel.StoreBeer.STORE_DB_ID, cv);
                            if (rowId1 > 0) {
                                Uri storesBeerUri = ContentUris.withAppendedId(StoresPreferencesModel.StoreBeer.CONTENT_URI, rowId1);
    //				        	Uri storesBeerUri = StoresPreferencesModel.Beers.withId(((Long)rowId1).toString());
                                getContext().getContentResolver().notifyChange(storesBeerUri, null);
                                count++;
                            }

                        }


                    }

                    //don't need to do this because the beer's list is already merged into what we've queried
    //	        	for (Entry<Integer, ContentValues> entry : lookupMap.entrySet()) {
    //	        		//set remaining values to not active
    //	        		ContentValues cvLeftOver = entry.getValue();
    //	        		cvLeftOver.put(StoresPreferencesModel.Beers.MODIFIED, now.getTime());
    //	        		cvLeftOver.put(StoresPreferencesModel.Beers.ACTIVE, true);
    //	        	}
                           */

                for (int i = 0; i < values.length; i++) {

                    ContentValues crCur = values[i];
//					Long rowId = crCur.getAsLong(BaseColumns._ID);
//					cv.put(StoresPreferencesModel.Beers.BEER_DB_ID, rowId);
//					String beerId = crCur.getAsString(Beers.BEER_ID);
//					crCur.remove(Beers.BEER_ID);
//					String memberDbId = uri.getPathSegments().get(1);
                    //"SELECT "
//					String beer_db_id_select = 
//					"SELECT " + Beers._ID + " FROM " + Beers.TABLE + " WHERE " + Beers.BEER_ID + " = ?";	

                    int resUpdate =
                            db.update(
                                    StoreBeer.TABLE,
                                    crCur,
                                    StoreBeer.BEER_DB_ID + "=? and " + StoreBeer.STORE_DB_ID + "=?",
                                    Util.asAr(crCur.getAsString(StoreBeer.BEER_DB_ID), crCur.getAsString(StoreBeer.STORE_DB_ID)));

                    long rowId = 0;
                    if (resUpdate <= 0) {


                        rowId = db.insert(StoreBeer.TABLE, StoreBeer.STORE_DB_ID, crCur);

                        if (rowId > 0) {
                            Uri noteUri = ContentUris.withAppendedId(StoreBeer.CONTENT_URI, rowId);
//							getContext().getContentResolver().notifyChange(noteUri,null);
                        }
                        count++;
                    } else {
//						getContext().getContentResolver().notifyChange(StoreBeer.CONTENT_URI,null);
                        count = count + resUpdate;
                    }

                    db.yieldIfContendedSafely();


                }

                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                setNullInternalWritableDatabase();
            }

            getContext().getContentResolver().notifyChange(StoreBeer.CONTENT_URI, null);
//	        ccc.close();
//	        t.close();
//	        long rowId = db.insert(STORES_TABLE_NAME, StoresPreferencesModel.NAME, values);
//	        if (rowId > 0) {
//	            Uri noteUri = ContentUris.withAppendedId(StoresPreferencesModel.CONTENT_URI, rowId);
//	            getContext().getContentResolver().notifyChange(noteUri, null);
//	            return noteUri;
//	        }


        } else if (matchedUri == BEERS) {
            SQLiteDatabase db = getInternalWritableDatabase();

            db.beginTransaction();
            try {

                for (int i = 0; i < values.length; i++) {

//		        	Log.d(TAG, "Cur CV: " + values[i].toString());

                    String beerId = values[i].getAsString(Beers.BEER_ID);
//		        	if ( beerId != null) {


                    int updateResult = db.update(Beers.TABLE, values[i], Beers.BEER_ID + "=?", Util.asAr(beerId));

                    if (updateResult > 0) {
                        count = count + updateResult;
//						getContext().getContentResolver().notifyChange(Beers.CONTENT_URI, null);
                    } else {
                        long rowId = db.insert(Beers.TABLE, Beers.BEER_ID, values[i]);
                        if (rowId > 0) {
                            Uri noteUri = ContentUris.withAppendedId(Beers.CONTENT_URI, rowId);
//							getContext().getContentResolver().notifyChange(noteUri,null);
                            count++;
                        }

                    }


                    db.yieldIfContendedSafely();

                }

                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                setNullInternalWritableDatabase();
            }
            getContext().getContentResolver().notifyChange(Beers.CONTENT_URI, null);
        } else if (matchedUri == MEMBERS_BEERS) {

//        	String member_id_beers_join =
//        		Beers.
//        		;
//        	String members_id_beers_join = MemberBeer.getMemberBeersJoin(); 	

            //Beers.TABLE + "," + MemberBeer.TABLE + "," + Members.TABLE

            SQLiteDatabase db = this.getInternalWritableDatabase();
            db.beginTransaction();
            try {

                for (int i = 0; i < values.length; i++) {

                    ContentValues crCur = values[i];
//					Long rowId = crCur.getAsLong(BaseColumns._ID);
//					cv.put(StoresPreferencesModel.Beers.BEER_DB_ID, rowId);
//					String beerId = crCur.getAsString(Beers.BEER_ID);
//					crCur.remove(Beers.BEER_ID);
//					String memberDbId = uri.getPathSegments().get(1);
                    //"SELECT "
//					String beer_db_id_select = 
//					"SELECT " + Beers._ID + " FROM " + Beers.TABLE + " WHERE " + Beers.BEER_ID + " = ?";	
                    String test = crCur.getAsString(MemberBeer.MEMBER_DB_ID);
                    String test2 = crCur.getAsString(MemberBeer.BEER_DB_ID);

//					if (!TextUtils.isEmpty(test) || !TextUtils.isEmpty(test2) ) {
//					Log.d(TAG, "Cur CV: " + crCur.toString());
//					Log.d(TAG, "Cur params: " + test + " " + test2);
//					}


                    int resUpdate =
                            db.update(
                                    MemberBeer.TABLE,
                                    crCur,
                                    MemberBeer.BEER_DB_ID + "=? and " + MemberBeer.MEMBER_DB_ID + "=?",
                                    Util.asAr(crCur.getAsString(MemberBeer.BEER_DB_ID), crCur.getAsString(MemberBeer.MEMBER_DB_ID)));

                    long resInsert = 0;
                    if (resUpdate <= 0) {


                        resInsert = db.insert(MemberBeer.TABLE, MemberBeer.MEMBER_DB_ID, crCur);
                        if (resInsert > 0) {
                            Uri noteUri = ContentUris.withAppendedId(Beers.CONTENT_URI, resInsert);
//							getContext().getContentResolver().notifyChange(noteUri,null);
                        }

                        count++;
                    } else {
                        count = count + resUpdate;
//						getContext().getContentResolver().notifyChange(MemberBeer.CONTENT_URI,null);
                    }

                    db.yieldIfContendedSafely();
                }


                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
                setNullInternalWritableDatabase();
            }
            getContext().getContentResolver().notifyChange(MemberBeer.CONTENT_URI, null);

        } else {
//        	throw new IllegalArgumentException("Unknown URI " + uri);
            count = super.bulkInsert(uri, values);
        }

//        throw new SQLException("Failed to insert row into " + uri);


        //TODO fix this
        return count;
    }

    @Override
    public Cursor query(
            Uri uri,
            String[] projection,
            String selection, String[] selectionArgs,
            String sortOrderIn) {

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        // If no sort order is specified use the default

        String groupBy = null;
        String sortOrder = null;
        String[] projectionNew = new String[]{};
        List<String> projectionAdd = new ArrayList<String>();

        List<String> selectionAdd = new ArrayList<String>();
        List<String> projectionArgsAdd = new ArrayList<String>();

        boolean isQueryParameters = false;


        switch (sUriMatcher.match(uri)) {

            case BEER_DB_ID:
                qb.appendWhere(BaseColumns._ID + "=" + uri.getPathSegments().get(1));

            case BEERS:
                qb.setTables(Beers.TABLE);
                qb.setProjectionMap(sBeersMap);
                sortOrder = Beers.DEFAULT_SORT_ORDER;
                break;

            case STORES_DB_ID:
                qb.appendWhere(BaseColumns._ID + "=" + uri.getPathSegments().get(1));
                break;

            case STORES:
                qb.setTables(Stores.TABLE);
                qb.setProjectionMap(sStoresMap);
                sortOrder = Stores.DEFAULT_SORT_ORDER;
                break;


            case STORES_BEERS_DB_ID:
                qb.appendWhere(BaseColumns._ID + "=" + uri.getPathSegments().get(1));
                break;

            case STORES_BEERS:
                qb.setTables(Stores.StoreBeer.getStoreBeerJoin());
                qb.setProjectionMap(sStoresBeersMap);
                sortOrder = Stores.StoreBeer.DEFAULT_SORT_ORDER;
                break;

            case STORES_BEERS_FILTER:
                if (true) {

                    sortOrder = Stores.StoreBeer.DEFAULT_SORT_ORDER;

                    String groupByQuery = uri.getQueryParameter(FlyingSaucerConv.GROUP_BY);
                    //        	String isTastedQuery = uri.getQueryParameter(FlyingSaucerConv.TASTED_BY);
                    String isActiveQuery = uri.getQueryParameter(FlyingSaucerConv.ACTIVE_BY);
                    String sortByQuery = uri.getQueryParameter(FlyingSaucerConv.SORT_BY);
                    String brewersFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_BREWERS);
                    String stylesFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_STYLES);
                    String contriesFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_COUNTRIES);
                    String containerFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_CONTAINER);
                    String storeDbIdQuery = uri.getQueryParameter(FlyingSaucerConv.BY_STORE_DB_ID);

                    String addStandardColumns = uri.getQueryParameter(FlyingSaucerConv.ADD_STANDARD_STORE_BEER_COLUMNS);

                    if (!TextUtils.isEmpty(addStandardColumns)) {

                        if (addStandardColumns.equals("true")) {
                            for (String curColumnToAdd : Stores.StoreBeer.STANDARD_COLUMNS) {
                                projectionAdd.add(curColumnToAdd);
                            }
//						projectionAdd.add(StoresPreferencesModel.StoreBeer.STORE_BEER_KEY);

                        }
                    }

                    if (!TextUtils.isEmpty(storeDbIdQuery)) {
                        projectionAdd.add(Stores.StoreBeer.STORE_DB_ID);
                        selectionAdd.add(Stores.StoreBeer.STORE_DB_ID + " = " + storeDbIdQuery);
                    }

                    if (!TextUtils.isEmpty(groupByQuery)) {
                        String columnName = onlyColumn(groupByQuery);
                        projectionAdd.add(columnName);
                        groupBy = groupByQuery;
                    }
                    if (!TextUtils.isEmpty(sortByQuery)) {
                        String columnName = onlyColumn(sortByQuery);
                        projectionAdd.add(columnName);
                        sortOrder = sortByQuery;
                    }

                    if (!TextUtils.isEmpty(isActiveQuery)) {
                        projectionAdd.add(Stores.StoreBeer.ACTIVE);
                        if (isActiveQuery.equals("true")) {
                            selectionAdd.add(StoreBeer.ACTIVE + " = 1 ");
                        } else {
                            selectionAdd.add(StoreBeer.ACTIVE + " = 0 ");
                        }
                    }

                    if (!TextUtils.isEmpty(brewersFilter)) {
                        projectionAdd.add(Beers.BREWER_NAME);
                        selectionAdd.add(Beers.BREWER_NAME + " IN ("
                                + brewersFilter + ") ");
                    }
                    if (!TextUtils.isEmpty(stylesFilter)) {
                        projectionAdd.add(Beers.STYLE_NAME);
                        selectionAdd.add(Beers.STYLE_NAME + " IN (" + stylesFilter
                                + ") ");
                    }
                    if (!TextUtils.isEmpty(contriesFilter)) {
                        projectionAdd.add(Beers.COUNTRY_NAME);
                        selectionAdd.add(Beers.COUNTRY_NAME + " IN ("
                                + contriesFilter + ") ");
                    }
                    if (!TextUtils.isEmpty(containerFilter)) {
                        projectionAdd.add(Beers.CONTAINER);
                        selectionAdd.add(Beers.CONTAINER + " = " + containerFilter);
                    }

                    isQueryParameters = true;
                    qb.setTables(Stores.StoreBeer.getStoreBeerJoin());
                    qb.setProjectionMap(sStoresBeersMap);

                }
                break;

            case MEMBERS_ID:
                qb.appendWhere(Members.MEMBERS_KEY + "=" + uri.getPathSegments().get(1));
                //fall through

            case MEMBERS:
                qb.setTables(Members.TABLE);
                qb.setProjectionMap(sMemberMap);
                sortOrder = Members.DEFAULT_SORT_ORDER;
                break;


            case MEMBERS_ID_BEERS:
                qb.appendWhere(MemberBeer.BEER_DB_ID + " = " + uri.getPathSegments().get(1));
                qb.setTables(MemberBeer.getMemberBeersJoin());
                qb.setProjectionMap(sMemberBeerMap);
                sortOrder = Beers.DEFAULT_SORT_ORDER;
                break;
            case MEMBERS_ID_BEERS_ID:
                qb.appendWhere(MemberBeer.MEMBER_DB_ID + " = " + uri.getPathSegments().get(1));
                qb.appendWhere(MemberBeer.BEER_DB_ID + " = " + uri.getPathSegments().get(3));
                qb.setTables(MemberBeer.getMemberBeersJoin());
                qb.setProjectionMap(sMemberBeerMap);
                sortOrder = Beers.DEFAULT_SORT_ORDER;
                break;

            case MEMBERS_BEERS:
                qb.setTables(MemberBeer.getMemberBeersJoin());
                qb.setProjectionMap(sMemberBeerMap);
                sortOrder = Beers.DEFAULT_SORT_ORDER;
                break;

            case MEMBERS_BEERS_ID:
                qb.setTables(MemberBeer.getMemberBeersJoin());
                qb.setProjectionMap(sMemberBeerMap);
                qb.appendWhere(BaseColumns._ID + " = " + uri.getPathSegments().get(2));
                sortOrder = Beers.DEFAULT_SORT_ORDER;
                break;

            case MEMBERS_BEERS_FILTER:

                String isTastedQuery = uri.getQueryParameter(FlyingSaucerConv.TASTED_BY);
                String isActiveQuery = uri.getQueryParameter(FlyingSaucerConv.ACTIVE_BY);

                String sortByQuery = uri.getQueryParameter(FlyingSaucerConv.SORT_BY);
                String groupByQuery = uri.getQueryParameter(FlyingSaucerConv.GROUP_BY);

                String brewersFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_BREWERS);
                String stylesFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_STYLES);
                String contriesFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_COUNTRIES);
                String containerFilter = uri.getQueryParameter(FlyingSaucerConv.FILTER_CONTAINER);

                String memberId = uri.getQueryParameter(FlyingSaucerConv.BY_MEMBER_ID);
                String memberDbId = uri.getQueryParameter(FlyingSaucerConv.BY_MEMBER_DB_ID);

                sortOrder = Members.MemberBeer.DEFAULT_SORT_ORDER;

                String addStandardColumns = uri.getQueryParameter(FlyingSaucerConv.ADD_STANDARD_MEMBER_BEER_COLUMNS);

                if (!TextUtils.isEmpty(addStandardColumns)) {

                    if (addStandardColumns.equals("true")) {
                        for (String curColumnToAdd : Members.MemberBeer.STANDARD_COLUMNS) {
                            projectionAdd.add(curColumnToAdd);
                        }
                        projectionAdd.add(Members.MemberBeer.MEMBER_BEER_KEY);

                    }
                }


                if (!TextUtils.isEmpty(memberId)) {
                    projectionAdd.add(Members.UFO_MEMBER_ID);
                    selectionAdd.add(Members.UFO_MEMBER_ID + " = " + memberId);
                }
                if (!TextUtils.isEmpty(memberDbId)) {
                    projectionAdd.add(MemberBeer.MEMBER_DB_ID);
                    selectionAdd.add(MemberBeer.MEMBER_DB_ID + " = " + memberDbId);
                }

                if (!TextUtils.isEmpty(groupByQuery)) {
                    String columnName = onlyColumn(groupByQuery);
                    projectionAdd.add(columnName);
                    groupBy = groupByQuery;
                }
                if (!TextUtils.isEmpty(sortByQuery)) {
                    String columnName = onlyColumn(sortByQuery);
                    projectionAdd.add(columnName);
                    sortOrder = sortByQuery;
                }

                if (!TextUtils.isEmpty(isTastedQuery)) {
                    projectionAdd.add(MemberBeer.IS_TASTED);
                    if (isTastedQuery.equals("true")) {
                        selectionAdd.add(MemberBeer.IS_TASTED + " = 1 ");
                    } else {
                        selectionAdd.add(MemberBeer.IS_TASTED + " = 0 ");
                    }
                }

                if (!TextUtils.isEmpty(isActiveQuery)) {
                    projectionAdd.add(Members.MemberBeer.ACTIVE);
                    if (isActiveQuery.equals("true")) {
                        selectionAdd.add(MemberBeer.ACTIVE + " = 1 ");
                    } else {
                        selectionAdd.add(MemberBeer.ACTIVE + " = 0 ");
                    }
                }

                if (!TextUtils.isEmpty(brewersFilter)) {
                    projectionAdd.add(Beers.BREWER_NAME);
                    selectionAdd.add(Beers.BREWER_NAME + " IN ("
                            + brewersFilter + ") ");
                }
                if (!TextUtils.isEmpty(stylesFilter)) {
                    projectionAdd.add(Beers.STYLE_NAME);
                    selectionAdd.add(Beers.STYLE_NAME + " IN (" + stylesFilter
                            + ") ");
                }
                if (!TextUtils.isEmpty(contriesFilter)) {
                    projectionAdd.add(Beers.COUNTRY_NAME);
                    selectionAdd.add(Beers.COUNTRY_NAME + " IN ("
                            + contriesFilter + ") ");
                }
                if (!TextUtils.isEmpty(containerFilter)) {
                    projectionAdd.add(Beers.CONTAINER);
                    selectionAdd.add(Beers.CONTAINER + " IN ("
                            + containerFilter + ") ");
                }


                qb.setTables(MemberBeer.getMemberBeersJoin());
                qb.setProjectionMap(sMemberBeerMap);

                isQueryParameters = true;

                break;


            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }


        if (isQueryParameters) {

        } else if (!TextUtils.isEmpty(sortOrderIn)) {
            sortOrder = sortOrderIn;
        }

        projectionNew = Util.asArReduce(projection, projectionAdd.toArray(new String[]{}));
        if (projectionNew.length <= 0) {
            projectionNew = null;
        }

        if (!TextUtils.isEmpty(selection)) {
            selectionAdd.add(selection);
        }
        String selectionNew = getAndedStrings(selectionAdd);
        String[] selectionNewArgs = Util.asArNonReduce(selectionArgs);

//        Log.d(TAG, "Query: " + qb.buildQuery(projectionNew, selection, selectionArgs, groupBy, null, orderBy, null));
        // Get the database and run the query
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor c = qb.query(db, projectionNew, selectionNew, selectionNewArgs, groupBy, null, sortOrder);

//        Log.d(TAG,"Count: " + c.getCount());

        // Tell the cursor what uri to watch, so it knows when its source data changes
        c.setNotificationUri(getContext().getContentResolver(), uri);


//        db.yieldIfContendedSafely();

        return c;

    }

    public static final String onlyColumn(String groupByQuery) {
        String lower = groupByQuery.toLowerCase();
        if (lower.contains(" ")) {
            if (lower.contains(" asc") ||
                    lower.contains(" desc")
                    ) {
                return groupByQuery.substring(0, groupByQuery.indexOf(" "));
            } else {
                return groupByQuery;
            }

        } else {
            return groupByQuery;
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
//        SQLiteDatabase db = getInternalWritableDatabase();
//        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        SQLiteDatabase db = this.getInternalWritableDatabase();
        int count = 0;


        switch (sUriMatcher.match(uri)) {
            case BEERS:
                count = db.update(Beers.TABLE, values, where, whereArgs);
                break;

            case BEER_DB_ID:
                String beerDbId = uri.getPathSegments().get(1);
                count = db.update(Beers.TABLE, values, Beers.BEERS_KEY + "=" + beerDbId
                        + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                break;

            case STORES_BEERS:

//                count = super.update(uri,values,where,whereArgs);
                count = db.update(Stores.StoreBeer.TABLE, values, where, whereArgs);


                break;

            case STORES:
//                         db.replace(Stores.TABLE,Stores.NUMBER, values);
                count = db.update(Stores.TABLE, values, where, whereArgs);


                break;

            case STORES_DB_ID:
                String storeDbId = uri.getPathSegments().get(1);
                count = db.update(Stores.TABLE, values, Stores.STORES_KEY + "=" + storeDbId
                        + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);

//        	count = db.update(, values, where,whereArgs);

                break;

            case MEMBERS:
                count = db.update(Members.TABLE, values, where, whereArgs);
                break;

            case MEMBERS_ID:
                String memberDbId = uri.getPathSegments().get(1);
                count = db.update(Members.TABLE, values, Members.MEMBERS_KEY + "=" + memberDbId
                        + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                break;

            case MEMBERS_BEERS:
                count = db.update(MemberBeer.TABLE, values, where, whereArgs);
                break;

//        case STORES_BEERS_DB_ID:
//        	//TODO
//        	String storeDbId2 = uri.getPathSegments().get(1);
//            count = db.update(StoresPreferencesModel.Beers.STORES_BEERS_TABLE_NAME, values, Util.mergeWithPeriod( StoresPreferencesModel.Beers.STORES_BEERS_TABLE_NAME ,StoresPreferencesModel.Beers._ID) + "=" + storeDbId2
//                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
//        	
//        	
//        	break;


            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);

//        db.yieldIfContendedSafely();

        return count;
    }

    //Utilities

    public static String toTableColumn(String table, String column) {
        return table + "." + column;
    }

/*    *//**
     * @deprecated Use {@link StoreBeer#getStoreBeerJoin()} instead
     *//*
    @Deprecated
    private static final String getStoreBeerJoin() {
        return StoreBeer.getStoreBeerJoin();
    }

    *//**
     * @deprecated Use {@link MemberBeer#getMemberBeersJoin()} instead
     *//*
    @Deprecated
    public static final String getMemberBeersJoin() {
        return MemberBeer.getMemberBeersJoin();
    }*/

    public static final String getAndedStrings(List<String> qList) {

        StringBuilder sb = new StringBuilder();
//		for (String cur : qList) {
//			if (TextUtils.isEmpty(cur)) {
//				qList.remove(cur);
//			}
//		}
        if (qList.size() <= 0) {
            return "";
        }
        for (int i = 0; i < qList.size(); i++) {
            String t = qList.get(i);
            if (i != qList.size() - 1) {
                if (!TextUtils.isEmpty(t)) {
                    sb.append(t);
                    sb.append(" AND ");
                }
            } else {
                if (!TextUtils.isEmpty(t)) {
                    sb.append(t);
                }
            }
        }


        return sb.toString();
    }

    //Static
    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "beers", BEERS);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "beers/#", BEER_DB_ID);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "beers/filter", BEERS_FILTER);

        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "stores", STORES);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "stores/#", STORES_DB_ID);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "stores/beers", STORES_BEERS);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "stores/beers/#", STORES_BEERS_ID);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "stores/beers/filter", STORES_BEERS_FILTER);

        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members", MEMBERS);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/#", MEMBERS_ID);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/beers", MEMBERS_BEERS);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/beers/#", MEMBERS_BEERS_ID);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/#/beers", MEMBERS_ID_BEERS);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/#/beers/#", MEMBERS_ID_BEERS_ID);

//        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/beers/dates/#", MEMBERS_BEERS_TASTED_DATES_ID);
        sUriMatcher.addURI(FlyingSaucerConv.AUTHORITY, "members/beers/filters", MEMBERS_BEERS_FILTER);


        sBeersMap = new HashMap<String, String>();

        sBeersMap.put(Beers.BEERS_KEY, Beers.BEERS_KEY + " as " + BaseColumns._ID);

        sBeersMap.put(Beers.BEER_ID, Beers.BEER_ID);
        sBeersMap.put(Beers.COUNTRY_ID, Beers.COUNTRY_ID);
        sBeersMap.put(Beers.BREWER_ID, Beers.BREWER_ID);
        sBeersMap.put(Beers.STYLE_ID, Beers.STYLE_ID);

        sBeersMap.put(Beers.RAW_NAME, Beers.RAW_NAME);
        // child
        sBeersMap.put(Beers.NAME, Beers.NAME);
        sBeersMap.put(Beers.CAN, Beers.CAN);
        sBeersMap.put(Beers.NAME_SUBSCRIPT, Beers.NAME_SUBSCRIPT);

        sBeersMap.put(Beers.CONTAINER, Beers.CONTAINER);
        // child
        sBeersMap.put(Beers.BOTTLE, Beers.BOTTLE);
        sBeersMap.put(Beers.DRAUGHT, Beers.DRAUGHT);

        sBeersMap.put(Beers.DESCRIPTION, Beers.DESCRIPTION);
        sBeersMap.put(Beers.CITY, Beers.CITY);
        sBeersMap.put(Beers.COUNTRY_NAME, Beers.COUNTRY_NAME);
        sBeersMap.put(Beers.STYLE_NAME, Beers.STYLE_NAME);
        sBeersMap.put(Beers.BREWER_NAME, Beers.BREWER_NAME);
        sBeersMap.put(Beers.AVERAGE_RATING, Beers.AVERAGE_RATING);

        sStoresMap = new HashMap<String, String>();
        sStoresMap.put(Stores.STORES_KEY, Stores.STORES_KEY + " as " + BaseColumns._ID);
        sStoresMap.put(Stores.NAME, Stores.NAME);
        sStoresMap.put(Stores.URL_NAME, Stores.URL_NAME);
        sStoresMap.put(Stores.URL, Stores.URL);
        sStoresMap.put(Stores.NUMBER, Stores.NUMBER);
        sStoresMap.put(Stores.UPDATED_DATE, Stores.UPDATED_DATE);
        sStoresMap.put(Stores.CREATION_DATE, Stores.CREATION_DATE);

        sMemberMap = new HashMap<String, String>();
        sMemberMap.put(Members.MEMBERS_KEY, Members.MEMBERS_KEY + " as " + BaseColumns._ID);
        sMemberMap.put(Members.CARD_NUMBER, Members.CARD_NUMBER);
        sMemberMap.put(Members.PASSWORD, Members.PASSWORD);
        sMemberMap.put(Members.PASSWORD_HASH, Members.PASSWORD_HASH);
        sMemberMap.put(Members.STORE_NUMBER, Members.STORE_NUMBER);
        sMemberMap.put(Members.UFO_MEMBER_ID, Members.UFO_MEMBER_ID);
        sMemberMap.put(Members.UFO_HOME_NAME, Members.UFO_HOME_NAME);
        sMemberMap.put(Members.UFO_HOME_NUMBER_BEERS, Members.UFO_HOME_NUMBER_BEERS);
        sMemberMap.put(Members.UFO_HOME_NUMBER_TOTAL_BEERS, Members.UFO_HOME_NUMBER_TOTAL_BEERS);
        sMemberMap.put(Members.UFO_HOME_USERNAME, Members.UFO_HOME_USERNAME);
        sMemberMap.put(Members.UFO_IS_CURRENT_USER, Members.UFO_IS_CURRENT_USER);
        sMemberMap.put(Members.UFO_LOGIN_AUTO_LOGIN, Members.UFO_LOGIN_AUTO_LOGIN);
        sMemberMap.put(Members.UFO_LOGIN_NON_MEMBER, Members.UFO_LOGIN_NON_MEMBER);
        sMemberMap.put(Members.UFO_LOGIN_REMEMBER, Members.UFO_LOGIN_REMEMBER);
        sMemberMap.put(Members.CREATION_DATE, Members.CREATION_DATE);
        sMemberMap.put(Members.UPDATED_DATE, Members.UPDATED_DATE);
        sMemberMap.put(Members.BEERS_REFRESHED_DATE, Members.BEERS_REFRESHED_DATE);
        sMemberMap.put(Members.UFO_ORIGIN_DATE, Members.UFO_ORIGIN_DATE);
        sMemberMap.put(Members.UFO_MOU_MEMBER, Members.UFO_MOU_MEMBER);


        sMemberBeerMap = new HashMap<String, String>();
        sMemberBeerMap.put(MemberBeer.MEMBER_BEER_KEY, MemberBeer.MEMBER_BEER_KEY + " as " + BaseColumns._ID);
        sMemberBeerMap.put(MemberBeer.MEMBER_DB_ID, MemberBeer.MEMBER_DB_ID);
        sMemberBeerMap.put(MemberBeer.BEER_DB_ID, MemberBeer.BEER_DB_ID);

        sMemberBeerMap.put(MemberBeer.ACTIVE, MemberBeer.ACTIVE);
        sMemberBeerMap.put(MemberBeer.COMMENTS, MemberBeer.COMMENTS);
        sMemberBeerMap.put(MemberBeer.TASTED_DATE, MemberBeer.TASTED_DATE);


        sMemberBeerMap.put(MemberBeer.RATING, MemberBeer.RATING);
        sMemberBeerMap.put(MemberBeer.CREATION_DATE, MemberBeer.CREATION_DATE);
        sMemberBeerMap.put(MemberBeer.UPDATED_DATE, MemberBeer.UPDATED_DATE);
        sMemberBeerMap.put(MemberBeer.IS_TASTED, "(NOT " + MemberBeer.TASTED_DATE + " ISNULL)" + " as " + MemberBeer.IS_TASTED);
        sMemberBeerMap.put(MemberBeer.SIMPLE_TASTED_DATE, "strftime('%m-%d-%Y', datetime( (" + MemberBeer.TASTED_DATE + "/1000) , 'unixepoch', 'localtime') )" + " as " + MemberBeer.SIMPLE_TASTED_DATE);
        sMemberBeerMap.put(MemberBeer.SIMPLE_CREATION_DATE, "strftime('%m-%d-%Y', datetime( (" + MemberBeer.CREATION_DATE + "/1000) , 'unixepoch', 'localtime') )" + " as " + MemberBeer.SIMPLE_CREATION_DATE);

        sMemberBeerMap.putAll(sBeersMap);
        sMemberBeerMap.putAll(sMemberMap);


        sStoresBeersMap = new HashMap<String, String>();
        sStoresBeersMap.put(Stores.StoreBeer.STORE_BEER_KEY, Stores.StoreBeer.STORE_BEER_KEY + " as " + BaseColumns._ID);
        sStoresBeersMap.put(Stores.StoreBeer.STORE_DB_ID, Stores.StoreBeer.STORE_DB_ID);
        sStoresBeersMap.put(Stores.StoreBeer.BEER_DB_ID, Stores.StoreBeer.BEER_DB_ID);
        sStoresBeersMap.put(Stores.StoreBeer.ACTIVE, Stores.StoreBeer.ACTIVE);
        sStoresBeersMap.put(Stores.StoreBeer.CREATION_DATE, Stores.StoreBeer.CREATION_DATE);
        sStoresBeersMap.put(Stores.StoreBeer.UPDATED_DATE, Stores.StoreBeer.UPDATED_DATE);
        sStoresBeersMap.put(StoreBeer.SIMPLE_CREATION_DATE, "strftime('%m-%d-%Y', datetime( (" + StoreBeer.CREATION_DATE + "/1000) , 'unixepoch', 'localtime') )" + " as " + StoreBeer.SIMPLE_CREATION_DATE);

        sStoresBeersMap.putAll(sBeersMap);
        sStoresBeersMap.putAll(sStoresMap);


    }


}
